#include <iostream>

// const不仅可以修饰成员变量，还能修饰成员函数
// const修饰函数有三个地方可以放（仅这三个）
#if 0
    class Test 
    {
    public:
        // 1、修饰返回值：代表返回值不可修改（用引用或者指针去接它的时候才会生效，用变量去接不会有任何问题，因为只是拿值）
        const int& func()   // 返回了一个成员变量a的常引用
        {
            return a;
        }

    private:
        int a;
    };

    int main()
    {
        Test t;
        int a = t.func();   // 定义一个变量a去接函数的返回值，接的是值，所以不管返回的是const还是非const对它都没有影响，因为接的仅仅是值
        // int &b = t.func();  // 用引用去接函数返回的常引用，那就等于b是a的引用，但是a是const修饰，所以接的时候也要加上const
        const int &b = t.func();

        return 0;
    }
#endif

#if 0
    class Test 
    {
    public:
        // 2、修饰形参：保护形参（基本上也是用在指针和引用上，如果没有&，像const int a，那const加不加不重要，因为外面传进来的是值，就算改，改的也是形参a的值，对外面的值没有影响）
        void func(const int &a) // 常引用，代表这个形参a在这个函数中不可修改，保证数据传进来的安全
        {
            a++; // 传进来的不可以改
            this->a++;   // 自己的成员变量a是可以改的
        }

    private:
        int a;
    };

    int main()
    {
        Test t;

        return 0;
    }
#endif

#if 0
    class Test 
    {
    public:
        // 3、常成员函数：在这个函数中，成员变量不能修改，仅限成员变量
        void func(int b)const
        {
            a++;    // 成员变量a，不可修改
            b++;    // 传进来的b，可以修改
        }

    private:
        int a;
    };

    int main()
    {
        Test t;

        return 0;
    }
#endif

#if 1
    class Test 
    {
    public:
        // 卡bug：它不可能作用到内存上，如果真的想要限死某一个变量，不允许以任何形式修改，得限死到内存里面，也就是直接把内存标记为不可改，得把这个内存挪到常量区去
        // 这个const限定范围仅限于当前函数，直接作用于成员变量，这个c对它来说不是成员函数，只是传进来的参数而已，像这样转个弯，把a的引用再传进来，那肯定能改
        void func(int b, int &c)const
        {
            b++;
            c++;
        }

        int &get()
        {
            return a;
        }

    private:
        int a;
    };

    int main()
    {
        Test t;
        t.func(10, t.get());
        return 0;
    }
#endif
